﻿using HP.UtilsLib;
using HP.UtilsLib.Algorithms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.ApplicationModel.AppService;
using Windows.Foundation.Collections;
using Xiaowei.Diagnostics;

namespace Xiaowei.Services
{
    public class TTSPlayerWithNAudio : ITTSPlayer
    {

        private bool isPlaying = false;
        private bool playSuccess = false;
        public bool IsPlaying 
        {
            get 
            {
                return isPlaying;
            }
            private set
            {
                if(isPlaying!=value)
                {
                    isPlaying = value;
                    IsPlayingChanged?.Invoke(value);
                }
            }
        }
        public event Action<bool> IsPlayingChanged;
        public ITTSPlayService TTSPlayService => ServiceFactory.TTSPlayService;
        /// <summary>
        /// Set false when send tts play command and set true when tts playing or time out.
        /// after send tts command, the same thread will wait until 
        /// </summary>
        private ManualResetEvent waiter = new ManualResetEvent(true);
        public TTSPlayerWithNAudio()
        {
            TTSPlayService.TTSPlaying += (v) => {
                playSuccess = true;
                waiter.Set();
                Debug.WriteLine("TTSPlayerWithNAudio, tts is playing. To stop failsafeTimer.");
            };
            TTSPlayService.TTSPlayEnd += () => {
                IsPlaying = false;
                Debug.WriteLine("TTSPlayerWithNAudio, tts play Ended.");

            };

            TTSPlayService.TTSPlayFail += () => {
                IsPlaying = false;
                playSuccess = false;
                waiter.Set();
                Debug.WriteLine("TTSPlayerWithNAudio, tts play Failed.");
            };

            TTSPlayService.TTSPlayTimeout += (v) => {
                IsPlaying = false;
                playSuccess = false;
                waiter.Set();
                Debug.WriteLine($"TTSPlayerWithNAudio, tts play time out {v}.");
            };
        }

        private readonly object locker = new object();
        public bool Play(string url)
        {
            lock (locker)
            {
                Debug.WriteLine($"TTSPlayerWithNAudio.Play:{url}");
                Cancel();
                var md5 = Algorithm.DoMD5(url);
                //failsafeTimer.Start(3000);
                playSuccess = false;
                var wait = TaskAwaiterHelper.GetTaskAwaiter(
                    async () =>
                    {
                        return await TTSPlayService.PlayTTS(url,md5);
                    }
                );
                wait.Await();
                bool result = wait.GetResult();
                wait.Dispose();
                if(result)
                {
                    IsPlaying = true;
                    return true;
                }
                else
                {
                    Debug.WriteLine($"TTSPlayerWithNAudio.Play, Failed. url:{url}.");
                    return false;
                }
                
            }

        }

        public void Cancel()
        {
            lock (locker)
            {
                if (IsPlaying)
                {
                    Debug.WriteLine("TTSPlayerWithNAudioNAudio.Cancel");
                    TTSPlayService.PauseTTS();
                    IsPlaying = false;
                    Debug.WriteLine("TTSPlayerWithNAudioNAudio.Cancel end");
                }
            }
        }
    }
}
